iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
0
自我挑戰組

我的影像視覺定位學習筆記系列 第 22

day22-單目相機定位前置作業

  • 分享至 

  • xImage
  •  

calibration後續
我又試了兩組不同焦距的校正影像,而各自組的校正誤差都有些許不同
焦距變化蠻大的,但再投影誤差都在1附近。
而同一組相機參數,不同組影像也會校正出不同焦距,
推測應該是函式優化收斂的地方,可能落入局部最佳,
但是在自訂相機參數的情況下,再投影誤差都穩定在2以下,
此模式獲得的影像應該相對有較高的可信度。

接下來就是定位專案的開發,
接著前面的作業,我想讓讀入的影像以vector的形式儲存,
同樣的Keypoints 跟 descript也是
在型別的部分

std::vector<cv::Mat>descript_img;
std::vector<std::vector<cv::KeyPoint>>list_of_keypoints;

原先的一組影像的descript就是以一個mat儲存,
因此在讀入影像的時候就接著將影像丟入偵測子運算
並將其結果塞入vector儲存

for (size_t i = 0; i < imagelist.size(); i++)
{
    cv::Mat result;
    result = cv::imread(imagelist[i], cv::IMREAD_COLOR);
    cv::resize(result, result, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
 
    std::vector<cv::KeyPoint>tmp_keypoints;
    cv::Mat tmp_descript;
 
    detector->detectAndCompute(result, cv::noArray(), tmp_keypoints, tmp_descript);
    descript_img.push_back(tmp_descript);
    list_of_keypoints.push_back(tmp_keypoints);
}

而在影像定位的時候,輸入的影像是連續影像還是不連續影像會有不同的處理流程,
通常輸入的影像都會是有序的,
而在無序的情況下要先對影像的匹配結果做排序,比較相似的影像其成功匹配的數量也會比較高。
這邊暫時以無序的基本流程做開發,但如果你確定你輸入的影像是連續的,
基本上只要匹配相鄰的兩張相片的匹配情況,
所以假設我輸入的影像有6張
我的第1張照片會依序跟2~6張做匹配,
第2張照片會跟3~6張做匹配,
依此類推,
直到第4張照片跟第5張照片匹配結束。

cv::Ptr < cv::BFMatcher> match_description = cv::BFMatcher::create(cv::NORM_L2, false);
const float ratio_thresh = 0.7f;
std::vector<std::vector<std::vector<cv::DMatch>>> ALL_good_matches;
for (size_t i = 0; i < imagelist.size()-1; i++)
{
    std::vector<std::vector<cv::DMatch>>tmp_ith_img_match;
    for (size_t j = i+1; j < imagelist.size(); j++)
    {
        std::vector < std::vector< cv::DMatch >> knn_match_result;
        match_description->knnMatch(descript_img[i], descript_img[j], knn_match_result, 2);

        std::vector<cv::DMatch> good_matches;
        for (size_t k = 0; k < knn_match_result.size(); k++)
        {
            if (knn_match_result[k][0].distance < ratio_thresh * knn_match_result[k][1].distance)
            {
                good_matches.push_back(knn_match_result[k][0]);
            }
        }

        tmp_ith_img_match.push_back(good_matches);
        std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << good_matches.size() << std::endl;
    }
    ALL_good_matches.push_back(tmp_ith_img_match);
}

而每組的匹配的結果會先做一次ratio_test過濾,未來也可以做其他過濾方法,

std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << good_matches.size() << std::endl;

我在這邊先輸出各組匹配的影像id跟影像之間的匹配數量。
為了驗證結果之後為將匹配結果以drawMatches的方式表現出來。
https://ithelp.ithome.com.tw/upload/images/20191008/20121127LDKS3Li5BG.png

for (size_t i = 0; i < imagelist.size() - 1; i++)
{
    int count = 0;
    for (size_t j = i+1; j < imagelist.size(); j++)
    {
        cv::Mat imgL,imgR;

        imgL = cv::imread(imagelist[i], cv::IMREAD_COLOR);
        cv::resize(imgL, imgL, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
        imgR = cv::imread(imagelist[j], cv::IMREAD_COLOR);
        cv::resize(imgR, imgR, cv::Size(640, 480), 0, 0, CV_INTER_AREA);
        cv::Mat img_Match_Knn_ratio;
        if (ALL_good_matches[i][count].empty()) {
            continue;
        }
        std::cout << "imgL id: " << i << " imgR id: " << j << "has matched:" << ALL_good_matches[i][count].size() << std::endl;
        
        cv::drawMatches(imgL, list_of_keypoints[i], imgR, list_of_keypoints[j], ALL_good_matches[i][count], img_Match_Knn_ratio, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
        
        cv::imshow("img_Match_Knn_ratio", img_Match_Knn_ratio);
        cv::waitKey();
        count++;
    }
}

std::vector<std::vector<std::vector<cv::DMatch>>> ALL_good_matches;
這邊我還沒想號ALL_good_matches的資料型別,感覺應該還有其他比較適合的儲存型態,
第一層我放的是左邊image的id第二層則是右邊image的id
如果是六張影像的情況
第1層會是0~5其對應的第二層的size()應該會是5,4,3,2,1。
https://ithelp.ithome.com.tw/upload/images/20191008/20121127hHs7neD1D0.png


上一篇
day21-Camera calibration[再次挑戰心得筆記]
下一篇
day23-點雲的初始化
系列文
我的影像視覺定位學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言